package com.draven.mybatis.mapping;

import com.draven.mybatis.session.DravenSqlSession;
import org.apache.ibatis.binding.MapperProxy;


import java.lang.reflect.Method;

import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class DravenMapperProxyFactory<T> {
  private final Class<T> mapperInterface;

  private final Map<Method, DravenMapperProxy.MapperMethodInvoker> methodCache = new ConcurrentHashMap<>();

  public DravenMapperProxyFactory(Class<T> mapperInterface) {
    this.mapperInterface = mapperInterface;
  }

  public T newInstance(DravenSqlSession sqlSession) {
    final DravenMapperProxy<T> mapperProxy = new DravenMapperProxy<>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
  }

  protected T newInstance(DravenMapperProxy<T> mapperProxy) {
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, mapperProxy);
  }
}
